#include "AStarNode.hpp"
#include "Heuristics.hpp"

AStarNode::AStarNode(Puzzle& p, AStarNode* parent) :
    _puzzle(p),
    _parent(parent),
    _isCostComputed(false),
    _RCost(0),
    _HCost(0)
{
    if (parent != NULL)
        this->_RCost = parent->getRCost() + 1;
}

AStarNode::AStarNode(AStarNode const & cp) :
    _puzzle(cp._puzzle),
    _parent(cp._parent),
    _isCostComputed(cp._isCostComputed),
    _RCost(cp._RCost),
    _HCost(cp._HCost)
{

}

AStarNode& AStarNode::operator=(AStarNode const & cp)
{
    this->_parent = cp._parent;
    this->_puzzle = cp._puzzle;
    this->_isCostComputed = cp._isCostComputed;
    this->_RCost = cp._RCost;
    this->_HCost = cp._HCost;
    return *this;
}

AStarNode::~AStarNode()
{

}

Puzzle& AStarNode::getPuzzle()
{
    return this->_puzzle;
}

Puzzle const & AStarNode::getPuzzle() const
{
    return this->_puzzle;
}

void AStarNode::setPuzzle(Puzzle const & p)
{
    this->_puzzle.copy(p);
}

int AStarNode::getRCost() const
{
    return this->_RCost;
}

int AStarNode::getHCost() const
{
    return this->_HCost;
}

int AStarNode::getTotalCost() const
{
    return this->getRCost() + this->getHCost();
}

void AStarNode::setRCost(int cost)
{
    this->_RCost = cost;
}

void AStarNode::setHCost(int cost)
{
    this->_HCost = cost;
}

void AStarNode::setParent(AStarNode* parent)
{
    this->_parent = parent;
}

AStarNode* AStarNode::getParent()
{
    return this->_parent;
}

int AStarNode::computeCost(Puzzle const & solution)
{
    if (!this->_isCostComputed)
    {
        this->_HCost = Heuristics::manhattan(this->_puzzle, solution);
        this->_isCostComputed = true;
    }
    return this->_HCost;
}
